package com.gzsxy.esjy;

import com.alibaba.fastjson.JSON;

import com.gzsxy.esjy.common.Assert;
import com.gzsxy.esjy.common.SvException;
import com.gzsxy.esjy.mapping.MappingEntity;
import com.gzsxy.esjy.util.ReflectUtil;
import io.netty.handler.codec.http.multipart.FileUpload;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 自定义调度器
 * @author zhangxiaolong
 * @date 2022/7/6 9:36
 */
public class NettyDispatcher {
	
	@Autowired
	private ApplicationContext applicationContext ;
	
	/**
	 * 执行服务:GET请求与表单
	 * @param path 请求路径
	 * @param params 请求参数
	 * @param handWiredBeans
	 * @return
	 * @throws Exception
	 */
	public Object service(MappingEntity mappingEntity, String path, Map<String,Object> params) throws Exception{
		//方法参数FileUpload 、Integer
		Class<?>[] args = mappingEntity.getArgs() ;
		Class<?>[] argsEx = mappingEntity.getArgsEx();
		//参数名 file，expired
		String[] paramNames = mappingEntity.getParamNames() ;

		Object[] parmasList = new Object[paramNames.length] ;
		try {
			int i = 0 ;
			for (String name : paramNames) {
				//获取参数值
				Object object = params.get(name);
				//如果为基本类型
				if(ReflectUtil.isPrimitive(args[i])){
					this.setValue(args[i], (String)object, parmasList,i);
				}else if(name.equals(mappingEntity.getBodyName())){
					doPostParams(args[i], argsEx[i], parmasList,i,(String)object);
				//如果为文件上传
				}else if(args[i] == FileUpload.class ) {
					Assert.notTrue(object instanceof FileUpload, " parameter error");
					parmasList[i]= object ;
				}else if(args[i].isArray()) {
					if(object instanceof List<?>){
						//临时修改，兼容批量上传
						if(args[i] == List.class) {
							parmasList[i] = object ;
						}else {
							FileUpload[] uploads = new FileUpload[((List<?>)object).size()] ;
							parmasList[i] = ((List<?>)object).toArray(uploads);
						}
					}else {
						parmasList[i] = new FileUpload[] {(FileUpload) object} ;
					}
				
				}else {
					parmasList[i] = (ReflectUtil.convertMapToBean(args[i], params, false)) ;
				}
				i++ ;
			}
		}catch(Exception e) {
			throw SvException.getInstance(e.getMessage(), 400,e);
		}
		//mappingEntity.getClazz() FileUploadController
		Object excuteService = this.applicationContext.getBean(mappingEntity.getClazz()) ;
		//通过反射找到对应的方法进行执行该方法
		return  ReflectUtil.invokeMethod(excuteService, mappingEntity.getMethodName(),
					mappingEntity.getArgs(),parmasList) ;
	}

	public void tt(int a,int[] bb) {
		System.out.println(a+" "+bb);
	}
	
	
	public static void main(String[] args) throws Exception {
		NettyDispatcher nettyDispatcher = new NettyDispatcher();
		List<Object> l = new ArrayList<Object>() ;
		l.add(2);
		l.add(new int[]{1,2,3,4})  ;
		ReflectUtil.invokeMethod(nettyDispatcher, "tt",
				new Class<?>[] {int.class,int[].class},l.toArray()) ;
	}
	

	/**
	 * 处理post参数
	 * @param args
	 * @param argsEx
	 * @param parmasList
	 * @param object
	 * @throws Exception 
	 */
	private void doPostParams(Class<?> args, Class<?> argsEx, Object[] parmasList, int i,String object) throws Exception {
		if(object == null) {
			throw new Exception("'@RequestBody' param is null");
		}
		if(args == List.class){
			parmasList[i] = (JSON.parseArray(object, argsEx)) ;
		}else if(args == String.class){
			parmasList[i] = (object) ;
		}else{
			parmasList[i] = (JSON.parseObject(object, args)) ;
		}
	}
	
	/**
	 * 设置方法参数
	 * @param type
	 * @param value
	 * @param paramValue
	 */
	private void setValue(Class<?> type,String value,Object[] paramValue,int i){
		if(type == String.class){
			paramValue[i] = value ;
		}else if(type == int.class){
			if(value == null){
				paramValue[i] = 0 ;
			}else{
				paramValue[i] = Integer.parseInt(value) ;
			}
		}else if(type == Integer.class){
			if(value == null){
				paramValue[i] = null ;
			}else{
				paramValue[i] = Integer.parseInt(value) ;
			}
		}else if(type == Double.class){
			if(value == null){
				paramValue[i] = null ;
			}else{
				paramValue[i] = Double.parseDouble(value) ;
			}
		}else if(type == double.class){
			if(value == null){
				paramValue[i] = (double)0;
			}else{
				paramValue[i] = Double.parseDouble(value) ;
			}
		}else if(type == Float.class){
			if(value == null){
				paramValue[i] = null ;
			}else{
				paramValue[i] = Float.parseFloat(value) ;
			}
		}else if(type == float.class){
			if(value == null){
				paramValue[i] = 0F ;
			}else{
				paramValue[i] = Float.parseFloat(value) ;
			}
		}else if(type == Long.class){
			if(value == null){
				paramValue[i] = (null) ;
			}else{
				paramValue[i] = (Long.parseLong(value)) ;
			}
		}else if(type == long.class){
			if(value == null){
				paramValue[i] = (0L) ;
			}else{
				paramValue[i] = (Long.parseLong(value)) ;
			}
		}else if(type == Boolean.class){
			if(value == null){
				paramValue[i] = (null) ;
			}else{
				paramValue[i] = (Boolean.parseBoolean(value)) ;
			}
		}else if(type == boolean.class){
			if(value == null){
				paramValue[i] = (false) ;
			}else{
				paramValue[i] = (Boolean.parseBoolean(value)) ;
			}
		}
	}
	
}
